#include "exportVTK.h"
#include "Tools.h"

/*

  test_01 is a void function with all the interpolation procedure. Basically it creates a scalar field on baseMesh,
  in this case respecting a linear function, transmits those values to a second mesh (interpMesh), calculates the 
  errors and exports the solutions to vtk.

*/


//test_01 definition 
void test_prolongation(int argc,char **argv, int option, string filename){ 
    
    //Create pointers to the meshes
    pMesh coarse, fine;

    //initialize pointers
    coarse = MS_newMesh(0);
    fine = MS_newMesh(0);

    //load the meshes
    M_load(coarse, argv[1]);//base mesh
    M_load(fine, argv[2]);//mesh to be interpolated
    
    coarse->modifyState(2,0);
    coarse->modifyState(0,2);

    fine->modifyState(2,0);
    fine->modifyState(0,2);

    //create DataTransfer object
    cout << __LINE__ << endl;
    DataTransfer data_transfer(coarse,fine);
    cout << __LINE__ << endl;

    
    //generate scalar field on base mesh and on interpMesh (to check interpolation errors)
   // generateScalarField(coarse,data_transfer,option);
    cout << __LINE__ << endl;
    generateScalarField(coarse,data_transfer,option);
    cout << __LINE__ << endl;


    //interpolate
    data_transfer.setInterpolationOperator(LINEAR);
    cout << __LINE__ << endl;
    //data_transfer.setInterpolationOperator(QUADRATIC);
    cout << __LINE__ << endl;
    data_transfer.coarse_to_fine(coarse,fine);
    cout << __LINE__ << endl;

    //calculate the error
    calculate_Error(fine,data_transfer,option);

    MapSCDBL mapStringData;
    mapStringData["InterpolatedData"] = data_transfer.getInterpolatedData();
    exportSolutionToVTK(fine,filename,mapStringData);


    MapSCDBL mapStringBaseMeshData;
    mapStringBaseMeshData["BaseData"] = data_transfer.getScalarField_baseMesh();
    exportSolutionToVTK(coarse,"ScalaField_baseMesh.vtk",mapStringBaseMeshData);


    // LINEAR INTERPOLATION
    data_transfer.setInterpolationOperator(LINEAR);
    data_transfer.coarse_to_fine(coarse,fine);
    MapSCDBL mapStringData_linear;
    mapStringData_linear["Linear_Interpolation"] = data_transfer.getInterpolatedData();
    exportSolutionToVTK(fine,"Linear_Interpolation.vtk",mapStringData_linear);


    
}

void test_restriction(int argc,char **argv, int option, string filename){
    
  //Create pointers to the meshes
    pMesh coarse, fine;

    //initialize pointers
    coarse = MS_newMesh(0);
    fine = MS_newMesh(0);

    //load the meshes
    M_load(coarse, argv[1]);//base mesh
    M_load(fine, argv[2]);//mesh to be interpolated
    
    //creating basic structure
    coarse->modifyState(1,0);
    coarse->modifyState(0,1);

    fine->modifyState(1,0);
    fine->modifyState(0,1);

    
    coarse->modifyState(2,0);
    coarse->modifyState(0,2);

    fine->modifyState(2,0);
    fine->modifyState(0,2);

    //create DataTransfer object
    DataTransfer data_transfer(fine,coarse);
      
	//generate scalar field
    generateScalarField(fine,data_transfer,option);
    
    //interpolate
    //data_transfer.setRestrictionOperator(PURE_INJECTION);
    data_transfer.setRestrictionOperator(HALF_WEIGHTING);
    //data_transfer.setRestrictionOperator(FULL_WEIGHTING);
    data_transfer.fine_to_coarse(fine,coarse);
    
    //calculate the error
    calculate_Error(coarse,data_transfer,option);
    
    //export
    MapSCDBL mapStringData;
    mapStringData["InterpolatedData"] = data_transfer.getInterpolatedData();
    exportSolutionToVTK(coarse,filename,mapStringData);


    MapSCDBL mapStringBaseMeshData;
    mapStringBaseMeshData["BaseData"] = data_transfer.getScalarField_baseMesh();
    exportSolutionToVTK(fine,"Restriction_baseMeshField.vtk",mapStringBaseMeshData);

}


